package com.bifrost.service;

import com.bifrost.constant.BonusPointsSource;
import com.bifrost.constant.BonusPointsUpdatedDetail;
import com.bifrost.constant.BonusPointsUpdatedType;
import com.bifrost.entity.BonusPointsHistory;
import com.bifrost.entity.Customer;
import com.bifrost.entity.MerchantStore;
import com.bifrost.exception.BonusPointsNotEnoughException;
import com.bifrost.exception.ExternalOrderProcessException;
import com.bifrost.exception.OriginOrderNotFundException;
import com.bifrost.model.ExternalOrder;
import com.bifrost.model.vo.PageVO;
import org.springframework.data.domain.Page;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

/**
 * @author rangf
 * @date 2018/4/9
 */
public interface BonusPointsService {


    /**
     * 扣减会员积分
     * @param customer
     * @param orderNumber
     * @param originNumber
     * @param decrementValue
     * @param source
     * @param detail
     * @param remark
     */
    Long decrementBonusPoints(Customer customer, String orderNumber, String originNumber, BigInteger decrementValue, BonusPointsSource source, BonusPointsUpdatedDetail detail, String remark) throws BonusPointsNotEnoughException;

    /**
     * 扣减会员积分并保存原始数据
     * @param customer
     * @param orderNumber
     * @param originNumber
     * @param decrementValue
     * @param source
     * @param detail
     * @param remark
     * @param data
     */
    Long decrementBonusPoints(Customer customer, String orderNumber, String originNumber, BigInteger decrementValue, BonusPointsSource source, BonusPointsUpdatedDetail detail, String remark, String data) throws BonusPointsNotEnoughException;

    /**
     * 增加会员积分
     * @param customer
     * @param orderNumber
     * @param incrementValue
     * @param source
     * @param detail
     * @param remark
     */
    Long incrementBonusPoints(Customer customer, String orderNumber, BigInteger incrementValue, BonusPointsSource source, BonusPointsUpdatedDetail detail, String remark);

    /**
     * 增加会员积分并保存原始数据
     * @param customer
     * @param orderNumber
     * @param incrementValue
     * @param source
     * @param detail
     * @param remark
     * @param data
     */
    Long incrementBonusPoints(Customer customer, String orderNumber, BigInteger incrementValue, BonusPointsSource source, BonusPointsUpdatedDetail detail, String remark, String data);

    /**
     * 记录积分日志
     * @param customer
     * @param orderNumber
     * @param originNumber
     * @param changeValue
     * @param changeType
     * @param source
     * @param remark
     * @return
     */
    BonusPointsHistory saveBonusPointsHistory(Customer customer, String orderNumber, String originNumber, BigInteger changeValue, BonusPointsUpdatedType changeType, BonusPointsUpdatedDetail detail, BonusPointsSource source, String remark);

    /**
     * 记录积分日志并保存原始数据
     * @param store
     * @param cardNumber
     * @param orderNumber
     * @param originNumber
     * @param changeValue
     * @param changeType
     * @param source
     * @param remark
     * @param data
     * @return
     */
    BonusPointsHistory saveBonusPointsHistory(MerchantStore store, String cardNumber, String orderNumber, String originNumber, BigInteger changeValue, BonusPointsUpdatedType changeType, BonusPointsUpdatedDetail detail, BonusPointsSource source, String remark, String data) ;
        /**
         * 获取用户积分历史记录
         *
         * @param customer
         * @return
         */
    List<BonusPointsHistory> getBonusPointsHistories(Customer customer);
    /**
     * 返回指定会员、指定sku的积分率
     * <p>
     *     取数顺序：先获取sku上设置的积分率为null，则取自定积分规则，ratio值为0 则认为不积分
     * </p>
     *<p>
     *   ratio->积分率
     *   times->倍率
     *</p>
     * 注：促销积分率若为null默认为0即促销默认不积分
     * @param skuId
     * @param customer
     * @param promoApplied
     * @return
     */
    Map getBonusPointsRatio(Long skuId, Customer customer, boolean promoApplied);

    Map getBonusPointsRatio(String externalId, String categoryCode, Customer customer, boolean promoApplied);

    /**
     * 外部订单积分
     * @param externalOrder
     * @return
     * @throws ExternalOrderProcessException
     */
    Long processExternalOrder(ExternalOrder externalOrder) throws ExternalOrderProcessException, BonusPointsNotEnoughException,OriginOrderNotFundException;


    /**
     * 是否已经处理过积分  用#findProcessedHistory方法代替
     * @param orderNumber
     * @param loyaltyNo
     * @param type
     * @return
     */
    @Deprecated
    boolean hasProcessed(String orderNumber, String loyaltyNo, BonusPointsUpdatedType type);

    /**
     * 查询对应的历史记录
     * @param orderNumber
     * @param loyaltyNo
     * @param type
     * @return
     */
    BonusPointsHistory findProcessedHistory(String orderNumber, String loyaltyNo, BonusPointsUpdatedType type);

    /**
     * 校验消费者的积分在退货的时候是否足够扣减
     * @param orderNumber 购物时积分的原单号
     * @param storeCode 门店号
     * @return 大于等于0：当前消费者的积分扣减之后还剩余的积分  小于0：扣减本次积分还差的积分
     */
    Integer check(String orderNumber, String storeCode) throws OriginOrderNotFundException;

    /**
     * 返回积分历史
     *
     * @param cardNumber
     * @param merchantId
     * @param page
     * @param pageSize
     * @return
     */
    Page<BonusPointsHistory> getBonusPointsHistories(String cardNumber, Long merchantId, Integer page, Integer pageSize);

    /**
     * 重新处理异常订单
     * @param exeOrdeId
     * @return
     */
    Long processExceptionOrder(Long exeOrdeId) throws BonusPointsNotEnoughException, OriginOrderNotFundException;

    void addBonusPoints(Customer user, String addPointsValue, String remark, BonusPointsUpdatedDetail type);

    public BonusPointsHistory insertBonusPointsHistory(BonusPointsHistory bonusPointsHistory);
    PageVO findByPage(String startTime, String endTime,String name,List<Long> merchantStoreIdList, String cardNum, String number, Integer pageCode, Integer pageSize);

    Integer checkReturn(Long returnId) throws OriginOrderNotFundException;
}
